﻿Imports System.Net.FtpClient

Module Helper

    Function MatchExcludedFileList(ByVal _filename As String) As Boolean

        Dim _rt = False

        For Each _item In frm_main.GetSettings.ExcludedFileList

            If _filename Like _item Then
                _rt = True
            End If

        Next

        Return _rt

    End Function

    Function ParseConnectionModus(ByVal _modus As String) As System.Net.FtpClient.FtpDataConnectionType

        Dim _rt As FtpDataConnectionType

        Select Case _modus.ToString.ToLower

            Case "autopassive"

                _rt = FtpDataConnectionType.AutoPassive

            Case "autoactive"

                _rt = FtpDataConnectionType.AutoActive

            Case "eprt"

                _rt = FtpDataConnectionType.EPRT

            Case "epsv"

                _rt = FtpDataConnectionType.EPSV

            Case "pasv"

                _rt = FtpDataConnectionType.PASV

            Case "pasvex"

                _rt = FtpDataConnectionType.PASVEX

            Case "port"

                _rt = FtpDataConnectionType.PORT

            Case Else

                Throw New NotImplementedException

        End Select

        Return _rt

    End Function

    Function ReverseParseConnectionMode(ByVal _modus As System.Net.FtpClient.FtpDataConnectionType) As Integer

        Dim _rt As Integer = -1

        Select Case _modus

            Case FtpDataConnectionType.AutoPassive

                Return 0

            Case FtpDataConnectionType.AutoActive

                Return 1

            Case FtpDataConnectionType.EPRT

                Return 2

            Case FtpDataConnectionType.EPSV

                Return 3

            Case FtpDataConnectionType.PASV

                Return 4

            Case FtpDataConnectionType.PASVEX

                Return 5

            Case FtpDataConnectionType.PORT

                Return 6

        End Select

        Return _rt

    End Function

    Function ParseEncryption(ByVal _encryption As String) As System.Net.FtpClient.FtpEncryptionMode

        Dim _rt As FtpEncryptionMode

        Select Case _encryption.ToString.ToLower

            Case "none"

                _rt = FtpEncryptionMode.None

            Case "explizit (tls)"

                _rt = FtpEncryptionMode.Explicit

            Case "implizit (ssl)"

                _rt = FtpEncryptionMode.Implicit

            Case Else

                Throw New NotImplementedException

        End Select

        Return _rt

    End Function

    Function ReverseParseEncryption(ByVal _encryption As System.Net.FtpClient.FtpEncryptionMode) As Integer

        Dim _rt As Integer = -1

        Select Case _encryption

            Case FtpEncryptionMode.None

                Return 0

            Case FtpEncryptionMode.Explicit

                Return 1

            Case FtpEncryptionMode.Implicit

                Return 2

        End Select

        Return _rt

    End Function

    Function ParseEnconding(ByVal _encoding As String) As SFDL.File.CharacterEncoding.CharacterEncoding

        Dim _rt As SFDL.File.CharacterEncoding.CharacterEncoding

        Select Case _encoding.ToString.ToLower

            Case "standard"

                _rt = SFDL.File.CharacterEncoding.CharacterEncoding.Standard

            Case "utf-8"

                _rt = SFDL.File.CharacterEncoding.CharacterEncoding.UTF8

            Case "utf-7"

                _rt = SFDL.File.CharacterEncoding.CharacterEncoding.UTF7

            Case "ascii"

                _rt = SFDL.File.CharacterEncoding.CharacterEncoding.ASCII

            Case Else

                Throw New NotImplementedException

        End Select

        Return _rt

    End Function

    Function ParseListMethod(ByVal _method As String) As FtpListOption

        Dim _rt As FtpListOption = FtpListOption.AllFiles

        Select Case _method.ToLower

            Case "standard"

                _rt = FtpListOption.AllFiles

            Case "sizemodify"

                _rt = FtpListOption.SizeModify

            Case "size"

                _rt = FtpListOption.Size

            Case "nlist"

                _rt = FtpListOption.ForceList

            Case "ls"

                _rt = FtpListOption.UseLS

        End Select

        Return _rt

    End Function

    Function ReverseParseListMethod(ByVal _method As FtpListOption) As Integer

        Dim _rt As Integer = -1

        Select Case _method

            Case FtpListOption.AllFiles

                _rt = 0

            Case FtpListOption.SizeModify

                _rt = 1

            Case FtpListOption.Size

                _rt = 2

            Case FtpListOption.ForceList

                _rt = 3

            Case FtpListOption.UseLS

                _rt = 4

            Case Else

                _rt = 0

        End Select

        Return _rt

    End Function

    Function ReverseParseEncoding(ByVal _encoding As SFDL.File.CharacterEncoding.CharacterEncoding) As Integer

        Dim _rt As Integer = -1

        Select Case _encoding

            Case File.CharacterEncoding.CharacterEncoding.Standard

                Return 0

            Case File.CharacterEncoding.CharacterEncoding.UTF8

                Return 1

            Case File.CharacterEncoding.CharacterEncoding.UTF7

                Return 2

            Case File.CharacterEncoding.CharacterEncoding.ASCII

                Return 3

        End Select

        Return _rt

    End Function

    Function GetFTPConnectionOptions() As SFDL.File.ConnectionInfo

        Dim _rt As New SFDL.File.ConnectionInfo
        Dim _tools As New SFDL.Core.Tools

        _rt.Host = frm_main.txt_host.Text
        _rt.Port = frm_main.num_port.Value
        _rt.Username = frm_main.txt_username.Text
        _rt.Password = frm_main.txt_password.Text

        If String.IsNullOrWhiteSpace(_rt.Username) Or _rt.Username.ToLower.Equals("anonymous") Then
            _rt.AuthRequired = False
        Else
            _rt.AuthRequired = True
        End If

        If String.IsNullOrWhiteSpace(frm_main.txt_ftp_path.Text) Then
            _rt.DefaultPath = System.Net.FtpClient.FtpExtensions.GetFtpPath("\")
        Else
            _rt.DefaultPath = System.Net.FtpClient.FtpExtensions.GetFtpPath(frm_main.txt_ftp_path.Text)
        End If

        _rt.DataConnectionType = ParseConnectionModus(frm_main.comB_DataConnectionMode.Text)
        _rt.EncryptionMode = ParseEncryption(frm_main.ComB_Encryption.Text)
        _rt.CharacterEncoding = ParseEnconding(frm_main.ComB_Encoding.Text)
        _rt.ListMethod = ParseListMethod(frm_main.ComB_LIST.Text)
        _rt.DataType = FtpDataType.Binary

        If frm_main.chk_force_single_connection.Checked Then
            _rt.ForceSingleConnection = True
        Else
            _rt.ForceSingleConnection = False
        End If

        If frm_main.chk_special_mode.Checked Then
            _rt.SpecialServerMode = True
            _rt.DataStaleDetection = False
        End If

        Return _rt

    End Function

    Function SetupFTPConnection(ByVal _ftp_connection_options As SFDL.File.ConnectionInfo) As System.Net.FtpClient.FtpClient

        Dim _ftp_client As New System.Net.FtpClient.FtpClient
        Dim _tools As New SFDL.Core.Tools

        FtpTrace.AddListener(New CustomFTPLog)

        With _ftp_client

            If String.IsNullOrWhiteSpace(_ftp_connection_options.Username) And String.IsNullOrWhiteSpace(_ftp_connection_options.Password) Then
                .Credentials = New Net.NetworkCredential("anonymous", "anonymous@sfdl.net")
            Else
                .Credentials = New Net.NetworkCredential(_ftp_connection_options.Username, _ftp_connection_options.Password)
            End If

            .DataConnectionType = _ftp_connection_options.DataConnectionType
            .EncryptionMode = _ftp_connection_options.EncryptionMode
            .Host = _ftp_connection_options.Host
            .Port = _ftp_connection_options.Port
            .Encoding = _tools.ConvertCharacterEncoding(_ftp_connection_options.CharacterEncoding)

            If .EncryptionMode = FtpEncryptionMode.Explicit Then 'FTPS Workaround
                .DataConnectionEncryption = False
            Else
                .DataConnectionEncryption = True
            End If

            If _ftp_connection_options.ForceSingleConnection = True Then
                .EnableThreadSafeDataConnections = False
            End If

            If _ftp_connection_options.DataStaleDetection = False Then
                .StaleDataCheck = False
            End If

            If _ftp_connection_options.SpecialServerMode Then
                .SpecialServerMode = True
                .StaleDataCheck = False
            End If

            .NoPathAppend = True

        End With

        Return _ftp_client

    End Function

    ''' <summary>
    ''' Funktion zum Parsen eines FTP Connection Strings
    ''' </summary>

    Function ParseFTPConnectionString(ByVal _ftp_string As String) As SFDL.File.ConnectionInfo

        Dim _ftp_server As New SFDL.File.ConnectionInfo

        If String.IsNullOrEmpty(_ftp_string) = False And _ftp_string.StartsWith("ftp://") Then

            _ftp_server.Host = _ftp_string.Replace("ftp://", "")

            _ftp_server.Port = 21

            If _ftp_server.Host.Contains("@") Then
                _ftp_server.AuthRequired = True
                _ftp_server.Username = _ftp_server.Host.Split(":")(0).ToString
                _ftp_server.Password = _ftp_server.Host.Split(":")(1).ToString
                _ftp_server.Password = _ftp_server.Password.Remove(_ftp_server.Password.IndexOf("@"))
                _ftp_server.Host = _ftp_server.Host.Split("@")(1).ToString
            End If

            If _ftp_server.Host.Contains("/") Then
                _ftp_server.DefaultPath = _ftp_server.Host.Remove(0, _ftp_server.Host.IndexOf("/"))
                _ftp_server.Host = _ftp_server.Host.Remove(_ftp_server.Host.IndexOf("/"))
            End If

            If _ftp_server.Host.Contains("\") Then
                _ftp_server.DefaultPath = _ftp_server.Host.Remove(0, _ftp_server.Host.IndexOf("\"))
                _ftp_server.Host = _ftp_server.Host.Remove(_ftp_server.Host.IndexOf("\"))
            End If

            If _ftp_server.Host.Contains(":") Then
                _ftp_server.Port = Integer.Parse(_ftp_server.Host.Split(":")(1).ToString)
                _ftp_server.Host = _ftp_server.Host.Remove(_ftp_server.Host.IndexOf(":"))
            End If

        End If

        'Wenn angabe im Connection String leer ist aber textfeld gefüllt ist dann nehme Pfad aus dem Textfeld
        If String.IsNullOrWhiteSpace(_ftp_server.DefaultPath) = True And String.IsNullOrWhiteSpace(frm_main.txt_ftp_path.Text) = False Then
            _ftp_server.DefaultPath = frm_main.txt_ftp_path.Text
        End If

        '%20 Durch leerzeichen ersetzten
        If _ftp_server.DefaultPath.Contains("%20") Then
            _ftp_server.DefaultPath = _ftp_server.DefaultPath.Replace("%20", Space(1))
        End If

        _ftp_server.DataConnectionType = ParseConnectionModus(frm_main.comB_DataConnectionMode.Text)
        _ftp_server.EncryptionMode = ParseEncryption(frm_main.ComB_Encryption.Text)
        _ftp_server.CharacterEncoding = ParseEnconding(frm_main.ComB_Encoding.Text)
        _ftp_server.ListMethod = ParseListMethod(frm_main.ComB_LIST.Text)
        _ftp_server.DataType = FtpDataType.Binary

        If frm_main.chk_force_single_connection.Checked Then
            _ftp_server.ForceSingleConnection = True
        Else
            _ftp_server.ForceSingleConnection = False
        End If

        If frm_main.chk_special_mode.Checked Then
            _ftp_server.SpecialServerMode = True
            _ftp_server.DataStaleDetection = False
        End If

        Return _ftp_server

    End Function

    Sub ModifyConnection(ByVal _ftp_connection_info As SFDL.File.ConnectionInfo)

        frm_main.AdvancedSettingsExpander.IsExpanded = True

        frm_main.txt_host.Text = _ftp_connection_info.Host
        frm_main.txt_ftp_path.Text = _ftp_connection_info.DefaultPath
        frm_main.txt_username.Text = _ftp_connection_info.Username
        frm_main.txt_password.Text = _ftp_connection_info.Password
        frm_main.num_port.Value = _ftp_connection_info.Port
        frm_main.chk_force_single_connection.Checked = _ftp_connection_info.ForceSingleConnection
        frm_main.chk_special_mode.Checked = _ftp_connection_info.SpecialServerMode

        frm_main.ComB_Encoding.SelectedIndex = ReverseParseEncoding(_ftp_connection_info.CharacterEncoding)
        frm_main.ComB_Encryption.SelectedIndex = ReverseParseEncryption(_ftp_connection_info.EncryptionMode)
        frm_main.comB_DataConnectionMode.SelectedIndex = ReverseParseConnectionMode(_ftp_connection_info.DataConnectionType)
        frm_main.ComB_LIST.SelectedIndex = ReverseParseListMethod(_ftp_connection_info.ListMethod)

        frm_main.cmd_save_changes.Visible = True
        frm_main.cmd_save_changes.Enabled = True

    End Sub

    Sub LockConnectionBar()
        frm_main.SplitContainer_Main.Panel1.Enabled = False
        frm_main.CMS_SplitButton.Enabled = False
    End Sub

    Sub UnLockConnectionBar()
        frm_main.SplitContainer_Main.Panel1.Enabled = True
        frm_main.CMS_SplitButton.Enabled = True
    End Sub

    Sub ResetFTPConnectionOptions()

        frm_main.txt_host.Clear()
        frm_main.num_port.Value = 21
        frm_main.txt_username.Clear()
        frm_main.txt_password.Clear()
        frm_main.comB_DataConnectionMode.SelectedIndex = 0
        frm_main.ComB_Encryption.SelectedIndex = 0
        frm_main.ComB_Encoding.SelectedIndex = 0
        frm_main.txt_ftp_path.Clear()
        frm_main.chk_force_single_connection.Checked = False

    End Sub

    Function DirListDeep(ByVal _path As String, ByVal _packagename As String, ByVal _ftp_client As FtpClient, ByVal _list_option As FtpListOption, Optional ByVal _root_dir As String = "") As List(Of OLV_SFDL_Item)

        Dim _rt As New List(Of OLV_SFDL_Item)

        _ftp_client.SetWorkingDirectory(_path)

        For Each _item As FtpListItem In _ftp_client.GetListing("", _list_option)

            If _item.Type = FtpFileSystemObjectType.Directory Then

                Dim _tmp_list As New List(Of OLV_SFDL_Item)

                _tmp_list = DirListDeep(_item.FullName, _packagename, _ftp_client, _list_option, _root_dir)

                _rt.AddRange(_tmp_list)

            Else

                If _item.Type = FtpFileSystemObjectType.File Then

                    Dim _olv_item As New OLV_SFDL_Item

                    If MatchExcludedFileList(_item.Name) = False Then

                        With _olv_item

                            If Not String.IsNullOrEmpty(_root_dir) Then
                                .DirectoryRoot = _root_dir
                            End If

                            .DirectoryPath = _item.FullName.Replace(_item.Name, "")
                            .FileFullPath = _item.FullName
                            .FileName = _item.Name
                            .FileSize = _item.Size
                            .FileHash = String.Empty
                            .FileHashType = File.FileInfo.HashType.None
                            .PackageName = _packagename

                        End With

                        _rt.Add(_olv_item)

                    End If

                End If

            End If

        Next

        Return _rt

    End Function

End Module